import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
import React, { useState, useCallback } from "react";
import TreeView from "devextreme/ui/tree_view";
import DevSortable from "../../components-ui/express-components/DevSortable";
function findNode(treeView, index, key) {
    const nodeElement = treeView.element().querySelectorAll(".dx-treeview-node")[index];
    if (nodeElement) {
        return findNodeById(treeView.getNodes(), nodeElement.getAttribute("data-item-id"), key);
    }
    return null;
}
function findNodeById(nodes, id, key) {
    for (let i = 0; i < nodes.length; i += 1) {
        if (nodes[i].itemData[key] === decodeURI(id)) {
            return nodes[i];
        }
        if (nodes[i].children) {
            const node = findNodeById(nodes[i].children, id, key);
            if (node != null) {
                return node;
            }
        }
    }
    return null;
}
export function HocSortableGrid(WrappedComponent) {
    return React.forwardRef((props, ref) => {
        const { onSelectionChanged, ...restProps } = props;
        const [selectData, setSelectData] = useState([]);
        const myDragTemplate = (e) => {
            function foreachItem(item) {
                let str = "";
                for (let key in item) {
                    const data = item[key];
                    str += data + "\t";
                }
                return str;
            }
            return (_jsx("ul", { children: e.itemData.map((item, index) => {
                    return (_jsx("li", { style: { listStyle: "none" }, children: foreachItem(item) }, index));
                }) }));
        };
        const onDragEnd = (e) => {
            //TODO 暂时不考虑排序的问题，后台目前不支持
            if (!e.dropInsideItem) {
                return;
            }
            const treeElement = document.getElementById(props.treeDomId);
            if (treeElement) {
                const treeView = TreeView.getInstance(treeElement);
                props.gridDragEnd(e.itemData, findNode(treeView, e.toIndex, props.groupTreeExpr || props.keyExpr));
            }
        };
        //拖拽前可以做校验, 并且做itemData赋值
        //TODO 目前只针对选中的进行拖拽, 但是也可以获取到非选中状态时拖拽的数据 (FromData) 看需求怎样
        const onDragStart = (e) => {
            // 仅支持单个主键，目前不支持联合主键
            const keyExpr = props.keyExpr;
            let fromData = null;
            // 如果支持非checkbox选中的内容也可以被拖拽, 则表格必须要传递keyExpr
            if (e.fromIndex !== undefined && e.fromIndex !== null && keyExpr) {
                fromData = props.dataSource[e.fromIndex];
            }
            let mergeData = selectData;
            if (fromData) {
                // 查找并合并数据;  如果多选中包含了该内容则不合并.
                const exists = selectData.some((item) => item[keyExpr] === fromData[keyExpr]);
                if (!exists) {
                    mergeData = [...selectData, fromData];
                }
            }
            if (mergeData.length > 0) {
                e.itemData = mergeData;
            }
            else {
                e.cancel = true; //可以取消拖拽
            }
        };
        const onDragChange = (e) => {
            if (e.fromComponent === e.toComponent) {
                e.cancel = true;
            }
        };
        const hocSelectionChanged = useCallback((data) => {
            setSelectData(data.selectedRowsData);
            if (onSelectionChanged) {
                console.log("@@@ hocSelectionChanged", data);
                onSelectionChanged(data);
            }
        }, [selectData]);
        const handleAdd = (e) => {
            const { toIndex } = e;
            props.gridDragEnd(toIndex, props.dataSource[toIndex]);
        };
        return (_jsx(_Fragment, { children: _jsx(DevSortable, { filter: ".dx-data-row", group: props.group, data: props.treeDomId, allowDropInsideItem: true, dragRender: myDragTemplate, allowReordering: true, onDragStart: onDragStart, onDragEnd: onDragEnd, onDragChange: onDragChange, onAdd: handleAdd, children: _jsx(WrappedComponent, { ...restProps, onSelectionChanged: hocSelectionChanged, ref: ref }) }) }));
    });
}
export function HocSortableTree(WrappedComponent) {
    return React.forwardRef((props, ref) => {
        const onDragEnd = (e) => {
            console.log("@@@HocSortableTree ref", ref);
            console.log(`@@@HocSortableTree e.fromIndex：${e.fromIndex}`);
            console.log(`@@@HocSortableTree e.fromIndex：${e.toIndex}`);
            const { fromIndex, toIndex, dropInsideItem } = e;
            // 未移动  lzc 对应科目时的需求索引号相同是也要拖拽。
            // if (fromIndex === toIndex) {
            //   return;
            // }
            let action = "move"; //dev的移动可以理解为只有上方，toData就是表示要移动到该节点的上方.没有下方的概念
            if (dropInsideItem) {
                action = "in";
            }
            const treeElement = document.getElementById(props.treeDomId);
            const treeView = TreeView.getInstance(treeElement);
            // const currentGrid = props.gridData ? props.gridData[e.toIndex] : null;
            const fromData = findNode(treeView, e.fromIndex, props.keyExpr);
            let toData;
            // 原则: 为了确保如果是 横线的话=>一定在目标节点的上方， 如果是 in (方块), 确保目标节点正确;
            if (fromIndex < toIndex && action !== "in") {
                toData = findNode(treeView, toIndex + 1, props.keyExpr);
            }
            else {
                toData = findNode(treeView, toIndex, props.keyExpr);
            }
            if (treeView) {
                props.treeDragEnd(fromData, toData, action);
            }
        };
        const onDragStart = (e) => {
            if (props.gridDragStart) {
                console.log("@@@", props.gridDragStart);
                props.gridDragStart(e);
            }
        };
        return (_jsx(DevSortable, { filter: ".dx-treeview-item", group: props.group, allowDropInsideItem: true, allowReordering: true, onDragEnd: onDragEnd, onDragStart: onDragStart, children: _jsx(WrappedComponent, { ...props, id: props.treeDomId, ref: ref }) }));
    });
}
